package org.example.uhy.rest;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.uhy.openapi.dto.ResponseDto;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import java.nio.charset.StandardCharsets;

import static org.junit.Assert.assertEquals;

public class RestClient {
    MockMvc mvc;
    ObjectMapper objectMapper;
    String token;

    public RestClient(MockMvc mvc, ObjectMapper objectMapper, String token) {
        this.mvc = mvc;
        this.objectMapper = objectMapper;
        this.token = token;
    }

    public ResponseDto get(String uri) {
        try {
            MvcResult mvcResult = mvc.perform(
                    MockMvcRequestBuilders.get(uri)
                            .header("access-token", token)
            ).andReturn();

            int status = mvcResult.getResponse().getStatus();
            assertEquals(200, status);
            String content = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
            return objectMapper.readValue(content, ResponseDto.class);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public ResponseDto post(String uri, String body) {
        return doPost(uri, body, MediaType.APPLICATION_JSON);
    }

    public ResponseDto formPost(String uri, String body) {
        return doPost(uri, body, MediaType.APPLICATION_FORM_URLENCODED);
    }

    private ResponseDto doPost(String uri, String body, MediaType mediaType) {
        try {
            MvcResult mvcResult = mvc.perform(
                    MockMvcRequestBuilders.post(uri)
                            .header("access-token", token)
                            .contentType(mediaType)
                            .content(body)
            ).andReturn();

            int status = mvcResult.getResponse().getStatus();
            if (status != 200) {
                return ResponseDto.failed(mvcResult.getResponse().getStatus() + " " + mvcResult.getResponse().getErrorMessage());
            }
            String content = mvcResult.getResponse().getContentAsString(StandardCharsets.UTF_8);
            return objectMapper.readValue(content, ResponseDto.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}
